/* cl.ext.ajax 0.1*/
(
	function (factory) {
		if (typeof define === 'function' && define.amd) {
			define(['jquery'], factory);
		} else if (typeof module === 'object' && module.exports) {
			module.exports = function( root, jQuery ) {
				if ( jQuery === undefined ) {
					if ( typeof window !== 'undefined' ) {
						jQuery = require('jquery');
					}
					else {
						jQuery = require('jquery')(root);
					}
				}
				factory(jQuery);
			};
		} else {
			factory(jQuery);
		}
	}(
	function ($){
		"use strict";
		var defaultinfoLoad = {type:"dotmoveright",place:"body",timeout:500}; // body; box {boxId,height,nothingHtml,nothingHide,dataListLength}
		var defaultExtInfo={"language":"zh-CN"};
		var defaults = {infoLoad:defaultinfoLoad,infoExt:defaultExtInfo};
		var $modalLoadHtml={
			"init":function(type,place){
				return '<div class="data-loading data-loading-'+place+'"><div class="loading-bg"></div>'+
					'<div class="loading-center">'+this[type]()+
					'</div></div>';
			},
			"dotmoveright":function() {
				return '<div class="loading-center-absolute loading-dotmoveright-base">'+
					'<div class="loading-dotmoveright dotmoveright1"></div>'+
					'<div class="loading-dotmoveright dotmoveright2" style="left:20px;"></div>'+
					'<div class="loading-dotmoveright dotmoveright3" style="left:40px;"></div>'+
					'<div class="loading-dotmoveright dotmoveright4" style="left:60px;"></div>'+
					'<div class="loading-dotmoveright dotmoveright5" style="left:80px;"></div>'+
					'</div>';
			},
			"lineenlarge":function(){
				return '<div class="loading-center-absolute loading-lineenlarge-base">'+
					'<div class="loading-lineenlarge lineenlarge1"></div>'+
					'<div class="loading-lineenlarge lineenlarge2"></div>'+
					'<div class="loading-lineenlarge lineenlarge3"></div>'+
					'<div class="loading-lineenlarge lineenlarge4"></div>'+
					'<div class="loading-lineenlarge lineenlarge5"></div>'+
					'</div>';
			},
			"doublebounce":function(){
				return '<div class="loading-center-absolute loading-doublebounce-base">'+
					'<div class="loading-doublebounce doublebounce1"></div>'+
					'<div class="loading-doublebounce doublebounce2"></div>'+
					'</div>';
			},
			"bounce":function() {
				return '<div class="loading-center-absolute loading-bounce-base">' +
					'<div class="loading-bounce bounce1"></div>' +
					'<div class="loading-bounce bounce2"></div>' +
					'<div class="loading-bounce bounce3"></div>' +
					'</div>';
			},
			"circle":function(){
				return '<div class="loading-center-absolute loading-circle-base">'+
				'<div class="loading-circle-container circle-container1">'+
				'<div class="loading-circle circle1"></div>'+
				'<div class="loading-circle circle2"></div>'+
				'<div class="loading-circle circle3"></div>'+
				'<div class="loading-circle circle4"></div>'+
				'</div>'+
				'<div class="loading-circle-container circle-container2">'+
				'<div class="loading-circle circle1"></div>'+
				'<div class="loading-circle circle2"></div>'+
				'<div class="loading-circle circle3"></div>'+
				'<div class="loading-circle circle4"></div>'+
				'</div>'+
				'<div class="loading-circle-container circle-container3">'+
				'<div class="loading-circle circle1"></div>'+
				'<div class="loading-circle circle2"></div>'+
				'<div class="loading-circle circle3"></div>'+
				'<div class="loading-circle circle4"></div>'+
				'</div>'+
				'</div>';
			}
		};
		var $modalLoad={
			"box":{
				"show":function(options){
					var _thisBox=$.ExtCommon.isCheckString(options.boxId)?$(options.boxId):options.boxId;
					if(_thisBox.length>0){
						var optionBase= {"place":"box"};
						optionBase=$.ExtCommon.initMergeJson(optionBase,options);
						optionBase.nothingHtml=optionBase.nothingHtml?optionBase.nothingHtml:"暂无数据";
						optionBase.height=optionBase.height?optionBase.height:200;
						_thisBox.each(function(){
							var _this=$(this);
							_this.hide();
							var objParent=_this.closest(".datajsonload");
							var objBox=objParent.find(".datajson-load-content");
							if(objBox.length===0){
								objParent.append('<div class="datajson-load-box" style="display: none;"><div class="datajson-load-content" style="display: block"></div></div>');
								objBox=objParent.find(".datajson-load-content");
							}
							var objLoading=objBox.find(".data-loading");
							if(objLoading.length===0){
								var loadhtml=$modalLoadHtml.init(optionBase.type,optionBase.place);
								objBox.append(loadhtml);
							}
							var objNothing=objBox.find(".data-nothing");
							if(objNothing.length===0){
								var nothinghtml='<div class="data-nothing" style="display: none"><div><i class="fa fa-eye-slash"></i><span>'+optionBase.nothingHtml+'</span></div></div>';
								objBox.append(nothinghtml);
							}else{
								objNothing.hide()
							}
							var css={};
							if(optionBase.height!=="auto"){
                                css.height=optionBase.height+"px";
                                css["line-height"]=optionBase.height+"px";
							}
							objBox.parent().css(css).show();
							objBox.find(".data-loading").show();
						});
					}
				},
				"hide":function(options,cb){
                    var _thisBox=$.ExtCommon.isCheckString(options.boxId)?$(options.boxId):options.boxId;
					if(_thisBox.length>0){
						options.nothingHide=typeof options.nothingHide==="boolean"?options.nothingHide:false;
						options.dataListLength=options.dataListLength?options.dataListLength:0;
						_thisBox.each(function() {
							var _this = $(this);
							var objBox = _this.closest(".datajsonload").find(".datajson-load-box");
							objBox.find(".data-loading").fadeOut();
							if (options.dataListLength > 0 || options.nothingHide) {
								objBox.hide();
								_this.fadeIn();
							} else {
								objBox.show().find(".data-nothing").fadeIn();
								_this.hide();
							}
						});
						if(cb){setTimeout(cb,130)}
					}
				},
				empty :function(options){
					var _thisBox=$(options.boxId);
					if(_thisBox.length>0){
						_thisBox.each(function() {
							var _this = $(this);
							var objBox = _this.closest(".datajsonload").find(".datajson-load-box");
							objBox.hide();
							_this.hide();
						})
					}
				}
			},
			"body":{
				"show":function(options){
					var optionBase= {"place":"body"};
					optionBase=$.ExtCommon.initMergeJson(optionBase,options);
					var bodyLoading=$("#body_loading");
					if(bodyLoading.length===0){
						$("body").append($($modalLoadHtml.init(optionBase.type,optionBase.place)).attr("id","body_loading"));
						bodyLoading=$("#body_loading");
					}
					if(bodyLoading.is(":hidden")){
						bodyLoading.fadeIn(150);
					}else{
						bodyLoading.fadeOut(150);
					}
				},
				"hide":function(options,cb){
					var bodyLoading=$("#body_loading");
					if(bodyLoading.is(":hidden")){
						if(cb)cb()
					}else{
						bodyLoading.fadeOut(150);
						if(cb){setTimeout(cb,130)}
					}
				},
				empty:function(){

				}
			}
		};
		var $modalCommon={
			getDefaults :function () {
				return defaults
			},
			getOptions : function (options) {
				options=$.ExtCommon.isCheckEmpty(options)?{}:options;
				var optionBase =$.ExtCommon.initMergeJson(this.getDefaults(),options);
				optionBase.isloading=options.infoLoad && typeof options.infoLoad === "object";
				return optionBase
			},
			getCodeHttpMap:function(json,httpcode){
				var code=json[httpcode];
				return $.ExtCommon.isCheckEmpty(code)?"default":code
			},
			getCodeMsg:function(list,code,language){
				language=$.ExtCommon.isCheckEmpty(language)?"zh-CN":language;
				var errmsg="";
				var info=list[language];
				if(!$.ExtCommon.isCheckEmpty(info) && info[code]){
					errmsg=info[code]
				}
				return errmsg
			},
			buttonDisable:function(id,isshow) {
				if ( $.ExtCommon.isCheckEmpty(id))$(id).prop("disabled", isshow);
			},
			loadStart:function(options){
				$modalLoad[options.place].show(options);
			},
			loadEnd:function(options,cb){
				var timeEnd=new Date();
				var timeout=-1;
				if(options.timeStart){
					var timeDiff=timeEnd.getTime()-options.timeStart.getTime();
					timeout= (timeDiff-options.timeout)>0?0:Math.abs(timeDiff-options.timeout);
				}
				if(timeout>0){
					setTimeout(function () {
						$modalLoad[options.place].hide(options,cb);
					},timeout);
				}else {
					$modalLoad[options.place].hide(options,cb);
				}
			},
			loadEmpty:function(options){
				$modalLoad[options.place].empty(options);
			},
			loadAjaxRun:function(selfParent,options) {
				var selfModal=this;
				var timeStart=new Date();
				var actualDefaults = {
					beforeSend:function(xhr){
						var self = this;
						if(!$.ExtCommon.isCheckEmpty(self.infoExt["token"])){
							var t= $.ExtCommon.isCheckEmpty($.ExtAjaxGlobal.token)?selfParent.infoExtAjaxSend.tokenName:$.ExtAjaxGlobal.token;
							xhr.setRequestHeader(t, self.infoExt["token"]);
						}
						selfModal.buttonDisable(self["disableid"],true);
						if(self.isloading){
							self.infoLoad.timeStart=timeStart;
							selfModal.loadStart(self.infoLoad);
						}
					},
					success: function (res) {
						var self = this;
						if (self.successCallback) {
							var result = selfParent.initResult(res);
							if(self.isloading){
								selfModal.buttonDisable(self["disableid"],false);
								self.infoLoad.dataListLength=0;
								if(result.data && result.data[self.infoLoad["dataListName"]]){
									self.infoLoad.dataListLength= $.ExtCommon.isCheckEmpty(result.data[self.infoLoad["dataListName"]])?0:1;
								}
								selfModal.loadEnd(self.infoLoad,function(){
									self.successCallback(result);
								});
							}else{
								self.successCallback(result);
							}
						}
					},
					error:function(req){
						var self = this;
						selfModal.buttonDisable(self.disableid,false);
						var codeMsg=selfParent.getCodeHttpErrorMsg(req);
						if (self.successCallback) {
							if (self.isloading) {
								self.infoLoad.dataListLength=0;
								selfModal.loadEnd(self.infoLoad, function () {
									self.successCallback({success: false, msg: codeMsg});
								});
							} else {
								self.successCallback({success: false, msg: codeMsg});
							}
						}
					},
					complete:function(){
					}
				};
				var actualOptions=selfModal.getOptions(options);
				actualOptions= $.ExtCommon.initMergeJson(actualDefaults,actualOptions);
				selfParent.optionBase=actualOptions;
				$.ajax(actualOptions);
			}
		};
		var AjaxExtModal = function () {
			this.infoExtAjaxSend={tokenName:"token"};
			this.infoExtParam={};
			this.infoExtUrl={};
		};
		AjaxExtModal.prototype={
			getCodeMsg:function(code,defaultmsg){
				var self=this;
				var msg=$modalCommon.getCodeMsg(self.message,code,self.optionBase?self.optionBase.infoExt.language:"");
				msg =msg.length===0?(defaultmsg?defaultmsg:self.message[self.optionBase.infoExt.language].default):msg;
				return msg;
			},
			getCodeHttpMap:function(httpcode){
				var self=this;
				return $modalCommon.getCodeHttpMap(self.httpCodeMaping,httpcode);
			},
			getCodeHttpErrorMsg:function(req){
				var code=this.getCodeHttpMap(req.status);
                return this.getErrorMsg(code,req.statusText);
			},
			getErrorMsg:function(code,defmsg){
				var codeMsg=this.getCodeMsg(code,defmsg);
				if($.ExtCommon.isCheckEmpty(codeMsg)){codeMsg+=",请联系运营人员";}
				return codeMsg;
			},
			initGetDefault:function(options){
				return $modalCommon.getOptions(options);
			},
			initLoadRuning:function(options,cb){
				if(options.dataListLength===0){
					this.initLoadStart(options);
					if(cb)cb()
				}else{
					this.initLoadEnd(options,cb)
				}
			},
			initLoadStart:function(options) {
				options.timeStart=new Date();
				var optionBase=$.ExtCommon.initMergeJson(defaultinfoLoad,options);
				$modalCommon.loadStart(optionBase);
			},
			initLoadEnd:function(options,cb) {
				var optionBase=$.ExtCommon.initMergeJson(defaultinfoLoad,options);
				$modalCommon.loadEnd(optionBase,cb);
			},
			initLoadEmpty:function(options) {
				var optionBase=$.ExtCommon.initMergeJson(defaultinfoLoad,options);
				$modalCommon.loadEmpty(optionBase);
			},
			initResult:function(res) {
				var self=this;
				//self.optionBase=$modalCommon.getOptions();
				var temp={};
				if(!$.ExtCommon.isCheckEmpty($.ExtAjaxGlobal.convertResultCallback)){
					temp=$.ExtAjaxGlobal.convertResultCallback(res);
				}else{
					temp={ret:res.ret,success:false,msg:"",data:null};
					if(res){
						if(res.ret){
							temp.reqtype="ret";
							temp.code=res.ret.toString();
							if(temp.code==="200"){
								temp.success = true;
								temp.data = res.data;
							}else{
								if(temp.code==="20001"){
									window.location.href = "/login";
									return false;
								}else {
									temp.success = false;
									//temp.msg = res.err_msg;
									temp.msg=self.getCodeMsg(temp.code,res.err_msg);
								}
							}
							temp.err_msg=temp.msg;
						}else if(res.meta){
							temp.reqtype="meta";
							temp.success=res.meta.success;
							temp.msg=res.meta.message;
							temp.data = res.data;
							temp.meta=res.meta;
						}else{
							temp.reqtype="meta";
							temp.code="200";
							temp.success = true;
							temp.data = res;
						}
					}
				}

				return temp;
			},
			initAjax:function(options){
				switch(options.type.toUpperCase()) {
					case "GET":
						this.initGet(options);
						break;
					case "POST":
						this.initPost(options);
						break;
					case "PUT":
						this.initPut(options);
						break;
					case "DELETE":
						this.initPut(options);
						break;
					default:
						this.initGet(options);
				}
			},
			setExtUrl:function(jsonParam){
				this.infoExtUrl=$.ExtCommon.initMergeJson(this.infoExtUrl,jsonParam);
			},
			setExtParam:function(jsonParam){
				this.infoExtParam=$.ExtCommon.initMergeJson(this.infoExtParam,jsonParam);
			},
			mergeExtUrl:function(url){
				var newUrl="";
				if($.ExtCommon.isCheckEmpty(this.infoExtUrl)){
					newUrl=url
				}else{
					var arr=[];
					for(var k in this.infoExtUrl){
						if(this.infoExtUrl.hasOwnProperty(k)){
							arr.push(k+"="+this.infoExtUrl[k]);
						}
					}
					newUrl=url+(url.indexOf("?")===-1?"?":"&")+arr.join("&");
				}
				return newUrl;
			},
			mergeExtParam:function(data){
				if($.ExtCommon.isCheckEmpty(this.infoExtParam)){
					return data;
				}else{
					var tempParam= $.ExtCommon.isCheckEmpty(data)?{}:(typeof data==="string"?JSON.parse(data):data);
					tempParam=$.ExtCommon.initMergeJson(tempParam,this.infoExtParam);
					tempParam=typeof data==="string"?JSON.stringify(tempParam):tempParam;
					return tempParam
				}
			},
			initGet:function(options) {
				var optionBase={type:"GET",cache:false};
				options.url=this.mergeExtUrl(options.url);
				options.data=this.mergeExtParam(options.data);
				var actualOptions=$.ExtCommon.initMergeJson(optionBase,options);
				$modalCommon.loadAjaxRun(this,actualOptions)
			},
			initPost:function(options) {
				var optionBase={type:"POST",contentType: "application/json",dataType: "json"};
				options.url=this.mergeExtUrl(options.url);
				options.data=this.mergeExtParam(options.data);
				var actualOptions=$.ExtCommon.initMergeJson(optionBase,options);
				$modalCommon.loadAjaxRun(this,actualOptions)
			},
			initPut:function(options) {
				var optionBase={type:"PUT",contentType: "application/json",dataType: "json"};
				options.url=this.mergeExtUrl(options.url);
				options.data=this.mergeExtParam(options.data);
				var actualOptions=$.ExtCommon.initMergeJson(optionBase,options);
				$modalCommon.loadAjaxRun(this,actualOptions)
			},
			initDelete:function(options) {
				var optionBase={type:"DELETE",contentType: "application/json",dataType: "json"};
				options.url=this.mergeExtUrl(options.url);
				options.data=this.mergeExtParam(options.data);
				var actualOptions=$.ExtCommon.initMergeJson(optionBase,options);
				$modalCommon.loadAjaxRun(this,actualOptions)
			},
			initGetSimple:function(options){
				var option={
					url:options.url,data:options.param,
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				if(!$.ExtCommon.isCheckEmpty(options.isLoading)){
                    option.infoLoad=options.isLoading;
                }
				this.initGet(option);
			},
			initPostSimple:function(options){
				var option={
					url:options.url,data:JSON.stringify(options.param),
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				var isLoading= $.ExtCommon.isCheckEmpty(options.isLoading)?true:options.isLoading;
				if(isLoading){option.infoLoad={place:"body"};}
				this.initPost(option);
			},
			initPostFormSimple:function(options){
				var option={
					url:options.url,data:options.param,
					contentType:"application/x-www-form-urlencoded",
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				var isLoading= $.ExtCommon.isCheckEmpty(options.isLoading)?true:options.isLoading;
				if(isLoading){option.infoLoad={place:"body"};}
				this.initPost(option);
			},
			initPostFileSimple:function(options){
				var option={
					url:options.url,data:options.param,
					cache: false,
					processData: false,
					contentType: false,
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				var isLoading= $.ExtCommon.isCheckEmpty(options.isLoading)?true:options.isLoading;
				if(isLoading){option.infoLoad={place:"body"};}
				this.initPost(option);
			},
			initPutSimple:function(options){
				var option={
					url:options.url,data:JSON.stringify(options.param),
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				var isLoading= $.ExtCommon.isCheckEmpty(options.isLoading)?true:options.isLoading;
				if(isLoading){option.infoLoad={place:"body"};}
				this.initPut(option);
			},
			initDeleteSimple:function(options){
				var option={
					url:options.url,data:JSON.stringify(options.param),
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				var isLoading= $.ExtCommon.isCheckEmpty(options.isLoading)?true:options.isLoading;
				if(isLoading){option.infoLoad={place:"body"};}
				this.initDelete(option);
			},
			initGetPageData:function(options){
				var option={
					url:options.url,data:options.param,contentType: "application/json",dataType: "json",cache:false,
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				this.initGet(option);
			},
			initPostPageData:function(options){
				var option={
					url:options.url,data:JSON.stringify(options.param),contentType: "application/json",dataType: "json",cache:false,
					successCallback:options.successCallback,
					infoExt:{token:options.token}
				};
				this.initPost(option);
			}
		};
		$.ExtAjax = new AjaxExtModal;
		$.ExtAjax.Constructor = AjaxExtModal;
		$.ExtAjax.httpCodeMaping={
			"0":"-10000",
			"400":"-10400",
			"401":"-10401",
			"403":"-10403",
			"404":"-10404",
			"405":"-10405",
			"406":"-10406",
			"407":"-10407",
			"408":"-10408",
			"409":"-10409",
			"410":"-10410",
			"411":"-10411",
			"412":"-10412",
			"413":"-10413",
			"414":"-10414",
			"415":"-10415",
			"416":"-10416",
			"417":"-10417",
			"500":"-10500",
			"501":"-10501",
			"502":"-10502",
			"503":"-10503",
			"504":"-10504",
			"505":"-10505"
		};
		$.ExtAjax.message = {
			"zh-CN": {
				"default":"未知错误",
				"200":"成功",
				"-10000":"请求未发出，请检查是否被拦截",
				"-10400":"错误的请求",
				"-10401":"请求要求身份验证",
				"-10403":"请求被拒绝",
				"-10404":"找不到请求的地址",
				"-10405":"资源被禁止",
				"-10406":"无法接受",
				"-10407":"需要代理授权",
				"-10408":"接口等候请求时发生超时",
				"-10409":"接口在完成请求时发生冲突",
				"-10410":"请求的资源已永久删除",
				"-10411":"接口不接受不含有效内容长度标头字段的请求",
				"-10412":"接口未满足请求者在请求中设置的其中一个前提条件",
				"-10413":"接口无法处理请求，因为请求实体过大，超出接口的处理能力",
				"-10414":"请求的Url过长，接口无法处理",
				"-10415":"请求的格式不受请求页面的支持",
				"-10416":"请求范围不符合要求",
				"-10417":"接口未满足期望请求标头字段的要求",
				"-10500":"接口内部错误",
				"-10501":"接口无法识别请求方法",
				"-10502":"错误网关",
				"-10503":"接口不可用",
				"-10504":"网关超时",
				"-10505":"接口不支持请求中所用的 HTTP 协议版本",
				"-90001":"当前用户无新增功能"
			}
		};
		if($.ExtAjaxGlobal){
		}else{
			$.ExtAjaxGlobal = {
				token:null,
				convertResultCallback:null
			};
		}
	})
);